#ifndef _RC6_H_
#define _RC6_H_

#define EN_RC6_BASE64_ENCODE   //using base64 encode ciphertext


typedef enum {
    RC6_MODE_ECB = 0,   
    RC6_MODE_CBC = 1,  
    RC6_MODE_CFB = 2,  
    RC6_MODE_OFB = 3,   
    RC6_MODE_CTR = 4,    
} RC6Mode_t;
 
//填充方式
typedef enum {
    RC6_NoPadding = 0,  
    RC6_Zeros = 1,     
    RC6_ISO10126 = 2,  
    RC6_PKCS7 = 3,    
    RC6_ANSIX923 = 4,  
} RC6Padding_t;

struct rc6_opt
{
    unsigned char w;        /* plaintext word lenth (bits)*/
    unsigned char r;        /* encode round */
    unsigned char b;        /* key length (byte)*/
    unsigned char Sm;       /* S space is using malloc by rc6 lib ? */
    unsigned int *S;        /* Extended Key , require (2 * r + 4) space*/

};

#define RC6_BLOCK_SIZE 16   //just support 128bit
struct rc6_ctx
{
    struct rc6_opt opt;
    int mode;       // base on RC6Mode_t
    int padding;    // base on RC6Padding_t
    unsigned char pIV[RC6_BLOCK_SIZE];
    void (*ctr_alg)(void *Nonce, int counter);  //The content of pIV is passed in by default in the first parameter. The second parameter is round , counter=0,1,2
                                                //Store the output results in the space pointed to by Nonce
};

/**
 * @brief rc6_init
 * 
 * @param ctx rc6 context
 * @param key secret key
 * @param key_len key length
 * @param opt rc6 specific option
 * @param pIV offset
 * @return int 0 for success , else false
 */
int rc6_init(struct rc6_ctx* ctx, unsigned char *key, unsigned char key_len, unsigned char *pIV, struct rc6_opt *opt);

/**
 * @brief rc6_encrypt
 * 
 * @param ctx       rc6 context
 * @param plaintext plaintext
 * @param p_len     plaintext length
 * @param ciphertext ciphertext
 * @param c_len     output ciphertext length
 * @return int int 0 for success , else false
 */
int rc6_encrypt(struct rc6_ctx* ctx, unsigned char *plaintext,int p_len, unsigned char *ciphertext, int *c_len);
int rc6_decrypt(struct rc6_ctx* ctx, unsigned char *plaintext,int *p_len, unsigned char *ciphertext, int c_len);
int rc6_free(struct rc6_ctx* ctx);

#endif  /* _RC6_H_ */
